package com.andnnl.fileanalysis;

import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.StrUtil;
import com.andnnl.utils.FileCharsetUtil;
import com.andnnl.utils.ZipUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.List;
import java.util.function.Supplier;

/**
 * Created by chenss on 2021/6/2.
 */
public class FileAnalysisManage {
    private static final Logger logger = LoggerFactory.getLogger(FileAnalysisManage.class);
    private static HashMap<String, Supplier<FileAnalysis>> map = new HashMap<>();

    static {
        map.put("txt", () -> new TxtAnalysis());
        map.put("csv", () -> new CsvAnalysis());
        map.put("xlsx", () -> new XlsAnalysis());
        map.put("xls", () -> new XlsAnalysis());
    }

    /**
     * 文件读取
     *
     * @param file
     * @param listener
     * @param param
     */
    public static void analysis(File file, AnalysisListenerBase listener, AnalysisParam param) {
        param.reset();//重置记录/参数
        try {
            String fileEncode = !StrUtil.isAllBlank(param.getCharset()) ? param.getCharset() : FileCharsetUtil.getFileEncode(file);
//            String fileEncode =!StrUtil.isAllBlank(param.getCharset())?param.getCharset(): FileCharsetUtil.getCharset(file);
            param.setCharset(fileEncode);
            // 得到文件的扩展名(无扩展名时将得到全名)
            String ext = !StrUtil.isAllBlank(param.getExt()) ? param.getExt() : file.getName().substring(file.getName().lastIndexOf(".") + 1).toLowerCase();
            FileAnalysis extractor = map.get(ext).get();//每次使用都new一个新的,避免多线程问题
            logger.info("fileName:" + file.getName() + " fileEncode:" + fileEncode, " ext:" + ext);
            if (extractor == null) {
                listener.finish();//直接完成
            } else {
                //生成预览数据
                try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(file))) {
                    extractor.analysis(in, listener, param);
                }
            }
        } catch (ReadInterruptException e) {
            logger.info("解析文件中断");
//            throw new RuntimeException("解析文件中断");
        } catch (Exception ex) {
            logger.info("解析文件异常：" + ex.getMessage(), ex);
            throw new RuntimeException("解析文件异常",ex);
        }
    }

    public static void analysisZip(File zipFile, AnalysisListenerBase listener, AnalysisParam param) {
        List<String> list = ZipUtil.unzip(zipFile, "");//解压多个文件
        for (String fn : list) {
            analysis(new File(fn), listener, param);
        }
    }

    public static void analysisStringList(List<String> list, AnalysisListenerBase listener, AnalysisParam param) {
        param.reset();//重置记录/参数
        try {
            StringListAnalysis iter = new StringListAnalysis();
            if (IterUtil.isEmpty(list)) {
                listener.finish();//直接完成
            } else {
                //生成预览数据
                iter.analysis(list, listener, param);
            }
        } catch (Exception ex) {
            logger.info("解析文件异常：" + ex.getMessage(), ex);
        }
    }

}
